#!/bin/bash
#Source other function files
source ${ADORESCR}/fun/resfile.fun
source ${ADORESCR}/fun/plotting.fun

###### SOME FUNCTIONS

function ?
{
 h "$@"
}

function addrefpha2s_crop(){
	. ${ADORESCR}/fun/addrefpha2s_crop "${@}"
}

function archive(){
  . ${ADORESCR}/fun/archive ${@}
}

function ask()          # See "settings save" for example of use.
{
  while [ 1 -eq 1 ] ;
  do
    echo -n "$@" '[y/n] ' ; read ans
    case "$ans" in
      y*|Y*) return 0 ;;
      n*|N*) return 1 ;;
    esac
  done
}

function bold() 	#echo bold text.
{
# USAGE: 
#   bold "Text to print bold"
#
# Ex:
#   bold "This is important."
#
  echo -e "\033[1m${@}\033[0m"
}

function call(){
  functionCall=$@;
  #parse left of equal
  functionOutput=${functionCall%%=*} 
  #parse right of equal
  functionCall=${functionCall#*=}
  functionName=${functionCall%% *}
  #echo output..${functionOutput}..
  #echo call..${functionCall}..
  #echo name..${functionName}..
  #echo "setting output array"
  #echo "function output..${functionOutput}.."
  
  eval output_array=${functionOutput}
  #call function
  eval ${functionCall}
  
  arrayLen=${#output_array[@]}
  #loop over variables.
  #assign values to output variables 
  for (( k=0; k<${arrayLen}; k++ ))
  do
    # get the output name from the outputs array
    outputName=${functionName}_outputs[$k]
    # get the name of the functions original output variable
    outputName=${!outputName}
    # assign requestest output variable to original output variable
    #echo "${output_array[$k]}=${!outputName}"
    eval ${output_array[$k]}=\"${!outputName}\"
  done
  unset k output_array arrayLen outputName functionCall functionOutput functionName
}

testFunction_outputs=(output1 output2 output3) 
function testFunction(){
  output1=${2} #set the first output parameter to second input.
  output2=${1} # set the first input parameter to second output.
  output3=${3}
}
#echo "variable1=4"
#variable1=4
#echo "Initiating function call..."
#echo 'call (a b c)=testFunction ${variable1} ready breakfast ;'
#call "(a b c)=testFunction ${variable1} ready breakfast ;"
#echo "$a $b $c"
#unset a b c

function cds(){
  cd ${1}; settings load
}

function parseargs(){
  local options
  options="${1}"
  shift  
  while getopts "${options}" flag
  do
    eval export ${flag}=${OPTARG}
  done
  for ((k=1; k<$OPTIND; k++))
  do
    shift
  done
  unset flag OPTARG OPTIND
}  

function calculate_coh_multilook(){
  echo "$(( ${srp_multilook% *} * ${int_multilook% *} )) $(( ${srp_multilook#* } * ${int_multilook#* } ))"
}

function calculate_coh_winsize(){
  if [ $(( ${srp_multilook% *} * ${int_multilook% *} * ${srp_multilook#* } * ${int_multilook#* } )) -lt 7 ]; then
    echo "5 5" #if single look interferometry set the coherence to 5 5. We need to have some number of pixels for coherence. 
  elif [ $(( ${srp_multilook% *} * ${int_multilook% *} * ${srp_multilook#* } * ${int_multilook#* } )) -gt 24 ]; then
    # If the window is >=25 large then go with it. Do not multiply by 2x2.
    echo "$(( ${srp_multilook% *} * ${int_multilook% *} )) $(( ${srp_multilook#* } * ${int_multilook#* } ))"
  else
    # If the window is in the middle, multiply by 2. The minimum number of pixels will be 24.
    echo "$(( 2 * ${srp_multilook% *} * ${int_multilook% *} )) $(( 2 * ${srp_multilook#* } * ${int_multilook#* } ))"
  fi
}
  
function calculate_rs_dbow(){
  local stat=`readRes.sh $s_resfile process "oversample"`
  #To-Do: also check for m_resfile:oversample
  if [[ stat -eq 1 ]]; then
    cropSource="oversample"
  else
    cropSource="crop"
  fi
  # get a smaller dbow from master. Otherwise the resampling may fail. 
  local l0 lN p0 pN lshift pshift
  l0=`${ADORESCR}/readRes.sh ${s_resfile} ${cropSource} "^First_line"`
  lN=`${ADORESCR}/readRes.sh ${s_resfile} ${cropSource} "^Last_line"`
  p0=`${ADORESCR}/readRes.sh ${s_resfile} ${cropSource} "^First_pixel"`
  pN=`${ADORESCR}/readRes.sh ${s_resfile} ${cropSource} "^Last_pixel"`

  lshift=`${ADORESCR}/readRes.sh ${i_resfile} coarse_correl "Coarse_correlation_translation_lines"`
  pshift=`${ADORESCR}/readRes.sh ${i_resfile} coarse_correl "Coarse_correlation_translation_pixels"`
  if [ ${lshift} -lt 0 ]; then 
    l0=$((${l0}-${lshift}+${rs_az_buffer}))
    lN=$((${lN}-${rs_az_buffer}))
  else 
    l0=$((${l0}+${rs_az_buffer}))
    lN=$((${lN}-${lshift}-${rs_az_buffer}))
  fi
  if [ ${pshift} -lt 0 ]; then
    p0=$((${p0}-${pshift}+${rs_rg_buffer}))
    pN=$((${pN}-${rs_rg_buffer}))
  else
    p0=$((${p0}+${rs_rg_buffer}))
    pN=$((${pN}-${pshift}-${rs_rg_buffer}))
  fi
  #rs_dbow="${l0} ${lN} ${p0} ${pN}"
  echo "${l0} ${lN} ${p0} ${pN}"
}

function calculate_srp_multilook(){
  if [ ${slc_az_res:-isEmpty} == "isEmpty" ]; then
    echo "1 1" #single look is default
  elif [ ${slc_rg_res:-isEmpty} == "isEmpty" ]; then
    echo "1 1" #single look is default
  else
    echo "${slc_rg_res} ${slc_az_res}"
  fi
}

function crops()
{
  . ${ADORESCR}/fun/crops ${@} 
}

function error() 	#echo text to stderr.
{
  echo -e "${@}" >&2
}

function formatBytes(){
  local unitSize
  unitSize=`echo ${format} | tr -d [a-z]`
  if [[ "$format" == *c* ]] ; then
    echo $(( ${unitSize} * 2 ))
  else
    echo ${unitSize}
  fi
}

function getSystemEndianness()	# See saveas arcview for example
{
 local endianness=`echo -n I | od -to2 | head -n1 | cut -f2 -d" " | cut -c6`
 if [ ${endianness} -eq 1 ]; then
   echo -n "little"
 elif [ ${endianness} -eq 0 ]; then
   echo -n "big"
 else
   echo -n "unknown"
 fi
}
                            
function generateRandomString(){
  randomString=`date +%N | md5sum |md5sum`
  randomString=${randomString:1:8}; #get first 8 char
}

function canonicalPath(){
  #from http://snipplr.com/view/18026/canonical-absolute-path/  
  [ "${1:-isEmpty}" == "isEmpty" ] && echo "" || echo $(cd "$(dirname "$1")"; pwd -P)/$(basename "$1")
}

function cpDorisFiles(){
  . ${ADORESCR}/fun/cpDorisFiles ${@}
}

function giant()
{
  . ${ADORESCR}/fun/giant ${@} 
}

function i12s()
{
  . ${ADORESCR}/fun/i12s ${@} 
}

function max()
{
  echo ${@} | tr " " "\n"| awk 'NR==1 { max=$1 } { if ($1>max) max=$1;} END {printf "%f", max}'
}

function min()
{
  echo ${@} | tr " " "\n"| awk 'NR==1 { min=$1 } { if ($1<min) min=$1;} END {printf "%f", min}'
}

function mvDorisFiles(){
  . ${ADORESCR}/fun/mvDorisFiles ${@}
}

function pp()
{
#PREP, PRE-PROCESS
  #this is the default processing
  rm -f ${outputFolder}/${dorisProcess}.drs
  dorisProcess=${1}
  if [ -r "${ADOREFOLDER}/drs/${dorisVersion}/${dorisProcess}.drs" ]; then
    cat "${ADOREFOLDER}/drs/${dorisVersion}/${dorisProcess}.drs" | while read -r line; do
      newline=`eval echo -E ${line}`
      echo $newline >> ${outputFolder}/${dorisProcess}.drs
    done
  else
    echo "Unknown process ${dorisProcess}"
  fi
}

function p()
{
#PROCESS
  local fileName
  local dorisProcess=${1}
  shift; #shift so that I can pass the remaining parameters.
  #if file is given with full path run that file.
  if [ -f "${dorisProcess}" ]; then
  	. ${dorisProcess} ${@};
  #else check the scr/process to see if it is a process
  elif [ -f "${ADOREFOLDER}/scr/process/${dorisProcess}" ]; then
          . ${ADOREFOLDER}/scr/process/${dorisProcess}
  else
  # check path to see if we can find the file in the path
#    fileName=`find -name 'rs2pn' 2>/dev/null | head -n1`
#    if [ -f "${fileName}" ]; then
#      echo "Running: ${fileName} ${@}"
#      . ${fileName} ${@}
#    #else do default processing. Prepare drs file and run doris. 
    if [ -e "${ADOREFOLDER}/drs/${dorisVersion}/${dorisProcess}.drs" ]; then
 #     rm -f ${outputFolder}/${dorisProcess}.drs
 #     cat "${ADOREFOLDER}/drs/${dorisProcess}.drs" | while read line; do
 #       newline=`eval echo -E ${line}`
 #       echo $newline >> ${outputFolder}/${dorisProcess}.drs
 #     done    
      pp ${dorisProcess}
      doris ${outputFolder}/${dorisProcess}.drs
      [ $? -eq 0 ] && echo "${dorisProcess}: SUCCESS"
    else
      echo "Unknown process: ${dorisProcess}."
      lsprocess
    fi
  fi
}

function fileSize(){
 echo $(stat -c%s ${1})
}

function pn2rs(){
  . ${ADORESCR}/fun/pn2rs ${@}
}

function report(){
  . ${ADORESCR}/fun/report ${@}
}

function s()
{
#SHOW
  local newline line dorisProcess var variableNames varArr
  dorisProcess=${1}
  if [ -e "${ADOREFOLDER}/drs/${dorisVersion}/${dorisProcess}.drs" ]; then
    cat "${ADOREFOLDER}/drs/${dorisVersion}/${dorisProcess}.drs" | while read -r line; do
      newline=`eval echo -E ${line}`
      echo $newline 
    done
  elif [ "${dorisProcess}" == "result" ];then
    dorisProcess=`pn2rs ${2}`
    local resfile=`pn2rs -f ${2}`
    sed -n "/_Start_${dorisProcess}/,/End_${dorisProcess}/p" ${resfile}    
  else
    variableNames='eval echo \${!${dorisProcess}*}'
    variableNames=`eval ${variableNames}`    
    if [ -n "${variableNames}" ]; then
      for var in ${variableNames}
      do
        varArr="${var}[*]"
	echo "${var}=${!varArr}"
      done
    else
      echo "Unknown process or variable: ${dorisProcess}"
    fi
  fi
}

function setPS1()
{
local setDir

if [ -n "${u}" ]; then
  setDir=`dirname ${u}`
  cPWD=`canonicalPath "${PWD}"`
  if [ "${cPWD}" == "${setDir}" ]; then
    PS1="ADORE: "
  else
    PS1="!ADORE: "
  fi
else
  PS1="!ADORE: "
fi  
}

function strcmpi()          # See "settings save" for example of use.
{
  if [ `echo ${1} | tr [:upper:] [:lower:]` == `echo ${2} | tr [:upper:] [:lower:]` ];then
    return 0;
  else
    return 1;
  fi  
}

function checkInitialSettings(){
########################### CHECK INPUT - MAKE SUGGESTIONS#
[ "${projectFolder}" == "." ] && echo "projectFolder is set to \".\". Use with caution."
if [ ! -d "${dataFolder}" ]; then 
  echo "Please set dataFolder or run: settings init."
else
  [ -z "${master}" ] && echo "No scenes in dataFolder."
fi
if [ ! -e "${m_in_dat}" ]; then
  if [ -L "${m_in_dat}" ]; then
    echo "m_in_dat points to a broken link."
  elif [ -n "${master}" ]; then
    echo "dataFile (filename pattern for SLC) is not set correctly."
  fi
fi
if [ ! -e "${s_in_dat}" ]; then
  if [ -L "${s_in_dat}" ]; then
    echo "s_in_dat points to a broken link."
  elif [ -n "${slave}" ]; then
    echo "Can not find dataFile in slave data folder."
  fi
fi
[ "${runName}" == "default" ] && echo "runName is set to \"default\"" && echo "Any batch processing results (baselines, scripts with .adr ending) will be created under ${processFolder}/default"
}

function check(){
	. ${ADORESCR}/fun/check "${@}"
}

function deramp(){
	. ${ADORESCR}/fun/deramp "${@}"
}

function dem(){
	. ${ADORESCR}/fun/dem "${@}"
}

function dem2slant2h(){
	. ${ADORESCR}/fun/dem2slant2h "${@}"
}

function exclude(){
	. ${ADORESCR}/fun/exclude "${@}"
}

function h(){
	. ${ADORESCR}/fun/h "${@}"
}

function initialize(){
	. ${ADORESCR}/fun/initialize
}

function mask(){
	. ${ADORESCR}/fun/mask "${@}"
}

function m_fbd2fbs(){
	. ${ADORESCR}/fun/m_fbd2fbs "${@}"
}

function openInIpython(){
	. ${ADORESCR}/fun/openInIpython
}

function quejob(){
	. ${ADORESCR}/fun/quejob "$@"
}

function previousSteps(){
	. ${ADORESCR}/fun/previousSteps "$@"
}

function raster(){
	. ${ADORESCR}/fun/raster "$@"
}


function settings(){
	. ${ADORESCR}/fun/settings "$@"
}

function saveas(){
	. ${ADORESCR}/fun/saveas "${@}"
}

function scenes(){
	. ${ADORESCR}/fun/scenes "${@}"
}

function s_fbd2fbs(){
	. ${ADORESCR}/fun/s_fbd2fbs "${@}"
}

function superMasterResample(){
        . ${ADORESCR}/fun/superMasterResample "${@}"
}

function tutorial(){
	. ${ADORESCR}/fun/tutorial "${@}"
}

function undo(){
	. ${ADORESCR}/fun/undo "$@"
}

function view(){
	. ${ADORESCR}/fun/view "$@"
}

function visualize(){
 	. ${ADORESCR}/fun/visualize "$@"
}

function waitjob(){
	. ${ADORESCR}/fun/waitjob "$@"
}

####################################################
################### DORIS FUNCTIONS ################
####################################################
function coarsecorr(){
  p coarsecorr ${@}
}
 
function coarseorb(){
  p coarseorb
}
 
function coherence(){
  p coherence
}
 
function comprefdem(){
  p comprefdem
}
 
function comprefpha(){
  p comprefpha
}
 
function coregpm(){
  p coregpm
}
 
function demassist(){
  p demassist
}
 
function dinsar(){
  p dinsar
}

function estorbits(){
  p estorbits
}
 
function filtphase(){
  p filtphase
}
 
function filtrange(){
  p filtrange
}
 
function fine(){
  p fine
}
 
function geocode(){
  p geocode
}
 
function interfero(){
  p interfero
}
 
function m_crop(){
  p m_crop
}
 
function m_filtazi(){
  p m_filtazi
}
 
function m_ovs(){
  p m_ovs
}
 
function m_porbits(){
  p m_porbits
}
 
function m_readfiles(){
  p m_readfiles
}
 
function m_simamp(){
  p m_simamp
}
 
function m_timing(){
  p m_timing "$@"
}
 
function reltiming(){
  p reltiming
}
 
function resample(){
  p resample "$@"
}
 
function s_crop(){
  p s_crop
}

function s_crop2resample(){
	. ${ADORESCR}/fun/s_crop2resample "${@}"
}
 
function s_filtazi(){
  p s_filtazi
}
 
function slant2h(){
  p slant2h
}

function slant2htrick(){
  p slant2htrick
}
 
function s_ovs(){
  p s_ovs
}
 
function s_porbits(){
  p s_porbits
}
 
function s_readfiles(){
  p s_readfiles
}
 
function subtrrefdem(){
  p subtrrefdem
}
 
function subtrrefpha(){
  p subtrrefpha
}
 
function unwrap(){
  p unwrap ${@}
}
 
function baselines(){
  #p baselines
  p ${ADOREFOLDER}/templates/baselines.adr
}

#Have a new line at the end
